﻿using Microsoft.Extensions.DependencyInjection;
using VIA.ImageProcessing;
using VIA.Integration;
using VIA.Integration.Alarms;
using VIA.Integration.Automatics;
using VIA.Integration.Domain;
using VIA.Integration.Domain.Production;
using VIA.Integration.Hikvision;
using VIA.Presentation;
using VIA.Project.Domain.Devices;
using VIA.Project.Domain.Services;
using VIA.SiMoJi.Domain.Electronics;
using VIA.SiMoJi.Domain.Option;
using VIA.SiMoJi.Domain.Vision;
using VIA.VTPlatformService;
using VT.Framework.Vision2D.DrawingObject;
using static VIA.SiMoJi.Domain.Inspection.VisionStation;

namespace VIA.SiMoJi.Domain.Inspection
{
    public class VisionStation : StationBase<VisionStationOption>, ISuportInitialization
    {
        #region Field
        private CancellationTokenSource CancellationTokenSource;
        private IVTPlatformManager _platformManager;
        protected InspectorOption _inspectorOption;
        protected IDispatcher _dispatcherService;
        private IApplicationLog _applicationLog;
        private IProductionLine _productionLine;
        private int _col;
        private int _flyCaptureCount;
        private CaptureFlag _flyCaptureFlag;
        private AutoResetEvent _topCaptrueEvent = new(false);
        private AutoResetEvent _upCaptrueEvent = new(false);
        private AutoResetEvent _bottomCaptrueEvent = new(false);
        private List<RobotImagePoseGroup> _topCalibrationCache = new();
        public BanYunStation BanYunStation;
        public IProductionLine ProductionLine => _productionLine;
        #endregion

        #region Property
        public ICamera TopCamera { get; }
        public ICamera UpCamera { get; }
        public ICamera BottomCamera { get; }
        public ImageData TopImage { get; private set; }
        public ImageData UpImage { get; private set; }
        public ImageData BottomImage { get; private set; }
        public Electronic Electronic => Electronic.Default;

        private List<Task<BottomDuiWeiAlgorithmResult>> _bottomTasks1 = new();
        private List<Task<BottomDetectAlgorithmResult>> _bottomTasks2 = new();

        List<Task<UpImageAlgorithmResult>> _upTasks = new();

        private List<RobotImagePoseGroup> _robotImagePoseGroups = new();
        private List<Pose> _calibr1 = new();
        private List<Pose> _calibr2 = new();
        private bool _isUseSiMo1;

        #endregion

        public VisionStation(IServiceProvider service)
        {
            this.InitalizeAlarms();
            _platformManager = service.GetRequiredService<IVTPlatformManager>();
            _dispatcherService = service.GetRequiredService<IDispatcher>();
            _applicationLog = service.GetRequiredService<IApplicationLog>();
            _productionLine = service.GetRequiredService<IProductionLine>();
            _inspectorOption = service.GetRequiredService<IOptionRepository>().Get<InspectorOption>();
            LogGroup = LoggerCategory.RunningInfo;

            if (_inspectorOption.IsVirtualMode)
            {
                TopCamera = new VirtualCamera() { Id = "Virtual_Camera1", Name = "虚拟相机1" };
                UpCamera = new VirtualCamera() { Id = "Virtual_Camera2", Name = "虚拟相机2" };
                BottomCamera = new VirtualCamera() { Id = "Virtual_Camera3", Name = "虚拟相机3" };
            }
            else
            {
                TopCamera = new HikvisionCamera() { Id = nameof(TopCamera), Name = "顶部相机" };
                UpCamera = new HikvisionCamera() { Id = nameof(UpCamera), Name = "上相机" };
                BottomCamera = new HikvisionCamera() { Id = nameof(BottomCamera), Name = "下相机" };
            }
            Add(TopCamera, UpCamera, BottomCamera);
            //TopCamera.ImageReceived += TopCamera_ImageReceived;
            UpCamera.ImageReceived += UpCamera_ImageReceived;
            BottomCamera.ImageReceived += BottomCamera_ImageReceived;
        }

        #region Fuction

        private void TopCamera_ImageReceived(object? sender, ImageReceivedEventArgs e)
        {
            TopImage = e.Image;

            _topCaptrueEvent.Set();
        }

        private void UpCamera_ImageReceived(object? sender, ImageReceivedEventArgs e)
        {
            UpImage = e.Image;
            _flyCaptureCount++;
            //吸嘴7-1;因为刚刚好反过来
            if (!_flyCaptureLists.Any(x => x == _flyCaptureCount)) return;//判断飞拍点位集合存在就拍照，不存就忽略。
            var flyCaptureCount = Math.Abs((_flyCaptureCount - 8));
            var up_Camera_FlyCaptureFlowBlock1 = _isUseSiMo1 ? Option.Up_Camera_FlyCaptureFlowBlock1 : Option.Up_Camera_FlyCaptureFlowBlock2;
            var task = _productionLine.AddUpImage(e.Image, new ProductPart(_isUseSiMo1, _col, flyCaptureCount), up_Camera_FlyCaptureFlowBlock1);
            _upTasks.Add(task);
            _upCaptrueEvent.Set();
        }

        List<int> _flyCaptureLists { get; set; } = new List<int>(); //需要飞拍点位
        private void BottomCamera_ImageReceived(object? sender, ImageReceivedEventArgs e)
        {
            BottomImage = e.Image;
            _bottomCaptrueEvent.Set();
            _flyCaptureCount++;
            if (_flyCaptureFlag != CaptureFlag.Calib_0 && _flyCaptureFlag != CaptureFlag.Calib_1)
            {
                if (!_flyCaptureLists.Any(x => x == _flyCaptureCount)) return;//判断飞拍点位集合存在就拍照，不存就忽略。
            }
            if (_flyCaptureFlag == CaptureFlag.DuiWei_0)
            {
                //吸嘴7-1;因为刚刚好反过来
                var flyCaptureCount = Math.Abs((_flyCaptureCount - 8));
                var bottom_Camera_FlyCaptureFlowBlock1 = Option.Bottom_Camera_FlyCaptureFlowBlock1;
                if (_inspectorOption.IsUseUpReadBarcode)
                {
                    bottom_Camera_FlyCaptureFlowBlock1 = Option.Bottom_Camera_FlyCaptureFlowBlock1_NotBarcode;
                }
                var task = _productionLine.AddBottomDuiWeiImage(e.Image, new ProductPart(_isUseSiMo1, _col, flyCaptureCount), bottom_Camera_FlyCaptureFlowBlock1, Option);
                _bottomTasks1.Add(task);
            }
            else if (_flyCaptureFlag == CaptureFlag.DuiWei_1)
            {
                //吸嘴7-1;因为刚刚好反过来
                var flyCaptureCount = Math.Abs((_flyCaptureCount - 8));
                var bottom_Camera_FlyCaptureFlowBlock2 = Option.Bottom_Camera_FlyCaptureFlowBlock2;
                if (_inspectorOption.IsUseUpReadBarcode)
                {
                    bottom_Camera_FlyCaptureFlowBlock2 = Option.Bottom_Camera_FlyCaptureFlowBlock2_NotBarcode;
                }
                var task = _productionLine.AddBottomDuiWeiImage(e.Image, new ProductPart(_isUseSiMo1, _col, flyCaptureCount), bottom_Camera_FlyCaptureFlowBlock2, Option);
                _bottomTasks1.Add(task);
            }
            else if (_flyCaptureFlag == CaptureFlag.Detect_0)
            {
                var task = _productionLine.AddBottomDetectImage(e.Image, new ProductPart(_isUseSiMo1, _col, _flyCaptureCount), Option.Bottom_Camera_DetectFlowBlock1);
                _bottomTasks2.Add(task);
            }
            else if (_flyCaptureFlag == CaptureFlag.Detect_1)
            {
                //Option.Bottom_Camera_DetectFlowBlock2.FilePath = Option.ProjectFilePath;
                var task = _productionLine.AddBottomDetectImage(e.Image, new ProductPart(_isUseSiMo1, _col, _flyCaptureCount), Option.Bottom_Camera_DetectFlowBlock1);
                _bottomTasks2.Add(task);
            }
            else if (_flyCaptureFlag == CaptureFlag.Calib_0)
            {
                var flyCaptureCount = Math.Abs((_flyCaptureCount - 8));
                var task = _productionLine.AddBottomMarkOrCalibrationImage(e.Image, new ProductPart(_isUseSiMo1, _col, flyCaptureCount), Option.Bottom_Camera_FlyCaptureFlowBlock1);
                _bottomTasks1.Add(task);

            }
            else if (_flyCaptureFlag == CaptureFlag.Calib_1)
            {
                var flyCaptureCount = Math.Abs((_flyCaptureCount - 8));
                var task = _productionLine.AddBottomMarkOrCalibrationImage(e.Image, new ProductPart(_isUseSiMo1, _col, flyCaptureCount), Option.Bottom_Camera_FlyCaptureFlowBlock2);
                _bottomTasks1.Add(task);
            }
        }

        public async Task<ImageData> TopSnap()
        {
            Electronic.DO15_入料相机条光触发.Value = true;
            Electronic.DO16_入料相机背光触发.Value = true;
            await Task.Delay(300);
            TopImage = await TopCamera.SnapAsync(default, 3000);
            Electronic.DO15_入料相机条光触发.Value = false;
            Electronic.DO16_入料相机背光触发.Value = false;
            return TopImage;
        }

        /// <summary>
        /// 生产顶部相机拍照
        /// </summary>
        /// <returns></returns>
        public async Task<TopImageAlgorithmResult> TopCapture(bool isUnload = false)
        {
            var image = await TopSnap();
            var barcode = $"{DateTime.Now:HHmmss}";
            await _productionLine.StartAsync(new Product(barcode, 0));
            TopImageAlgorithmResult result = new TopImageAlgorithmResult();
            if (!isUnload)
            {
                result = await _productionLine.AddTopImage(image, new ProductPart(_isUseSiMo1, 0, 0), Option.Top_Camera_CaptureFlowBlock1, Option);
                result.Barcode = barcode;
            }
            else
            {
                result = await _productionLine.AddTopImageUnload(image, new ProductPart(_isUseSiMo1, 0, 0), Option.Top_Camera_CaptureFlowBlock1, Option);
                result.Barcode = barcode;
            }
            return result;
        }
        /// <summary>
        /// 顶部相机拍mark
        /// </summary>
        /// <param name="isAutoSave"></param>
        /// <returns></returns>
        public async Task<TopImageAlgorithmResult> TopMarkCapture(bool isAutoSave)
        {
            var image = await TopSnap();
            var barcode = $"Top_Mark_{DateTime.Now:HHmmss}";
            await _productionLine.StartAsync(new Product(barcode, 0));
            var result = await _productionLine.AddTopMarkImage(image, new ProductPart(_isUseSiMo1, 0, 0), Option.Top_Camera_CalibrationFlowBlock);
            if (result.Quality == Quality.Ok && isAutoSave)
            {
                Option.FeedTrayMarkPoint = result.Pose;
                Option.TopCameraDuiWeiParam.MarkPose = result.Pose;
                var recipe = Service.GetRequiredService<ICurrentRecipe>();
                recipe.Set(Id, Option);
                await recipe.SaveAsync();
            }
            return result;
        }

        /// <summary>
        /// 计算标定坐标
        /// </summary>
        /// <param name="pose"></param>
        /// <returns></returns>
        private List<Pose> CreateCalibrationPlatformPoses(Pose pose)
        {
            List<Pose> poses = new List<Pose>();
            double offsetX = Option.TopCameraDuiWeiParam.CalibrationOffset.X;
            double offsetY = Option.TopCameraDuiWeiParam.CalibrationOffset.Y;
            double offsetAngle = Option.TopCameraDuiWeiParam.CalibrationOffset.Angle;
            poses.Add(new Pose(pose.X - offsetX, pose.Y - offsetY, pose.Angle));
            poses.Add(new Pose(pose.X, pose.Y - offsetY, pose.Angle));
            poses.Add(new Pose(pose.X + offsetX, pose.Y - offsetY, pose.Angle));
            poses.Add(new Pose(pose.X - offsetX, pose.Y, pose.Angle));
            poses.Add(new Pose(pose.X, pose.Y, pose.Angle));
            poses.Add(new Pose(pose.X + offsetX, pose.Y, pose.Angle));
            poses.Add(new Pose(pose.X - offsetX, pose.Y + offsetY, pose.Angle));
            poses.Add(new Pose(pose.X, pose.Y + offsetY, pose.Angle));
            poses.Add(new Pose(pose.X + offsetX, pose.Y + offsetY, pose.Angle));
            return poses;
        }

        /// <summary>
        /// 顶部相机标定
        /// </summary>
        /// <param name="isAutoSave"></param>
        /// <returns></returns>
        public async Task<bool> TopCalibration(bool isAutoSave, CancellationToken cancellationToken)
        {
            try
            {
                Option = Recipe.Get<VisionStationOption>(Id);
                var robotPoses = CreateCalibrationPlatformPoses(Option.TopCameraDuiWeiParam.MarkPose);
                _topCalibrationCache.Clear();
                for (int i = 0; i < robotPoses.Count; i++)
                {
                    await BanYunStation.MoveXYAxis(robotPoses[i].X, robotPoses[i].Y, cancellationToken);
                    var image = await TopSnap();
                    await Task.Delay(500);
                    var barcode = $"Top_Mark_{DateTime.Now:HHmmss}";
                    await _productionLine.StartAsync(new Product(barcode, 0));
                    var result = await _productionLine.AddTopMarkImage(image, new ProductPart(_isUseSiMo1, 0, 0), Option.Top_Camera_CalibrationFlowBlock);
                    if (result.Quality != Quality.Ok)
                        return false;
                    _topCalibrationCache.Add(new RobotImagePoseGroup(new Pose(robotPoses[i].X, robotPoses[i].Y, 0), result.Pose));
                }
                CMatrix matrix = CMatrixEx.CalcMatrix(_topCalibrationCache.Select(x => x.ImagePose).ToArray(), _topCalibrationCache.Select(x => x.RobotPose).ToArray(), out double msc);
                if (isAutoSave)
                {
                    Option.TopCameraDuiWeiParam.CalibrateRobotImagePoseGroups = _topCalibrationCache.ToObservableCollection();
                    Option.TopCameraDuiWeiParam.Matrix = matrix;
                    var recipe = Service.GetRequiredService<ICurrentRecipe>();
                    recipe.Set(Id, Option);
                    await recipe.SaveAsync();
                }
                return true;
            }
            catch (Exception ex)
            {
                LogError(ex);
                return false;
            }
        }

        public async Task StartAsync(string barcode)
        {
            await _productionLine.StartAsync(new Product(barcode, 0));
        }

        /// <summary>
        /// 下相机第一次飞拍开始
        /// </summary>
        public async Task PrepearBottomFlyCapture(CaptureFlag captureFlag, bool isUseSiMo1, int col, string barcode)
        {
            _col = col;
            _flyCaptureCount = 0;
            _flyCaptureFlag = captureFlag;
            _isUseSiMo1 = isUseSiMo1;
            _bottomTasks1.Clear();
            _bottomTasks2.Clear();
            if (_productionLine.Current == null)
            {
                await _productionLine.StartAsync(new Product(barcode, 0));
            }
        }

        /// <summary>
        /// 下相机第一次飞拍开始(带有确定吸嘴上是有产品飞拍点位)
        /// </summary>
        public async Task PrepearBottomFlyCapture2(CaptureFlag captureFlag, bool isUseSiMo1, int col, string barcode, List<int> flyCaptureLists)
        {

            _col = col;
            _flyCaptureCount = 0;
            _flyCaptureFlag = captureFlag;
            _isUseSiMo1 = isUseSiMo1;
            _bottomTasks1.Clear();
            _bottomTasks2.Clear();
            _flyCaptureLists = flyCaptureLists;
            if (_productionLine.Current == null)
            {
                await _productionLine.StartAsync(new Product(barcode, 0));
            }
        }

        public async Task<bool> BottomRotationCenterCalibration(bool isUseSiMo1, CaptureFlag captureFlag, int index, bool isAutoSave, bool isRotationCenterCalibration)
        {
            var (isSuccess, results) = await GetBottomFlyCaptureResults1(captureFlag, [true, true, true, true, true, true, true]);
            if (index == 1)
            {
                if (isSuccess)
                {
                    _calibr1 = results.Select(x => x.Pose).ToList();
                }
            }
            else if (index == 2)
            {
                if (isSuccess)
                {
                    _calibr2 = results.Select(x => x.Pose).ToList();
                    NozzleCalibrationData[] calData = [new(), new(), new(), new(), new(), new(), new()];
                    for (int i = 0; i < 7; i++)
                    {
                        double deltX = _calibr1[i].X - _calibr2[i].X;
                        double deltY = _calibr1[i].Y - _calibr2[i].Y;
                        double r = Math.Sqrt(deltX * deltX + deltY * deltY) / 2;
                        var rc = new RotationCenter((_calibr1[i].X + _calibr2[i].X) * 0.5, (_calibr1[i].Y + _calibr2[i].Y) * 0.5, r);
                        var pose = new Pose(_calibr1[i].X, _calibr1[i].Y, _calibr1[i].Angle);
                        int j = 6 - i;
                        calData[j].RotationCenter = rc;
                        if (isRotationCenterCalibration)
                            calData[j].MarkPoint = pose;

                    }
                    if (isAutoSave)
                    {
                        if (isUseSiMo1) Option.NozzleCalibrationDatas = calData;
                        else Option.NozzleCalibrationDatas2 = calData;
                        var recipe = Service.GetRequiredService<ICurrentRecipe>();
                        recipe.Set(Id, Option);
                        await recipe.SaveAsync();
                    }
                }
            }
            return isSuccess;
        }

        /// <summary>
        /// 下相机第一次飞拍结束,
        /// </summary>
        /// <returns></returns>
        public async Task<(bool isSuccess, BottomDuiWeiAlgorithmResult[] results)> GetBottomFlyCaptureResults1(CaptureFlag captureFlag, bool[] hasProducts)
        {
            var length = hasProducts.Length;
            bool[] temp = new bool[length];
            for (int i = 0; i < length; i++)
            {
                temp[i] = hasProducts[length - 1 - i];
            }
            bool isSuccess = true;
            BottomDuiWeiAlgorithmResult[] results = [];
            if (_bottomTasks1.Count < 7)
            {
                await Task.Delay(1000);
            }
            if (_bottomTasks1.Count < 7)
            {
                return (false, results.ToArray());
            }
            results = await Task.WhenAll(_bottomTasks1);
            for (int i = 0; i < length; i++)
            {
                if (temp[i])
                {
                    isSuccess &= results[i].Quality == Quality.Ok;
                }
                else
                {
                    results[i].Offset = new();
                }
            }
            return (isSuccess, results);
        }
        /// <summary>
        /// 下相机第一次飞拍结束 第二种获取结果方法(1-6)
        /// </summary>
        /// <returns></returns>
        public async Task<(bool isSuccess, BottomDuiWeiAlgorithmResult[] results)> GetBottomFlyCaptureResults1_Funcation(CaptureFlag captureFlag, bool[] hasProducts)
        {
            if (_bottomTasks1.Count() < hasProducts.Count(x => x == true))
            {
                await Task.Delay(1000);
            }
            BottomDuiWeiAlgorithmResult[] results = new BottomDuiWeiAlgorithmResult[hasProducts.Count()];
            if (_bottomTasks1.Count() < hasProducts.Count(x => x == true))//延迟1000ms后，检测队列还是不满足数量就NG。
            {
                return (false, results);
            }
            var resultsTmep = await Task.WhenAll(_bottomTasks1);
            int resultsTmepIndex = 0;
            for (int i = 0; i < hasProducts.Count(); i++)
            {
                int numberAbs = Math.Abs(i - 6);
                if (hasProducts[numberAbs])//吸嘴有产品的
                {
                    if (resultsTmepIndex < resultsTmep.Count())
                    {
                        results[numberAbs] = resultsTmep[resultsTmepIndex];
                        resultsTmepIndex = resultsTmepIndex + 1;
                    }
                    else //吸嘴有产品的,但是检测结果集合未找到结果，也是NG
                    {
                        results[numberAbs] = new BottomDuiWeiAlgorithmResult();
                    }
                }
                else//吸嘴无产品的
                {
                    results[numberAbs] = new BottomDuiWeiAlgorithmResult();
                }
            }
            return (resultsTmep.All(x => x.Quality == Quality.Ok) ? true : false, results);
        }

        /// <summary>
        /// 下相机第二次飞拍结束
        /// </summary>
        /// <param name="hasProducts"></param>
        /// <returns></returns>
        public async Task<(bool isSuccess, bool[] results)> GetBottomFlyCaptureResults2(CaptureFlag captureFlag, bool[] hasProducts)
        {
            var length = hasProducts.Length;
            bool isSuccess = true;
            bool[] results = [false, false, false, false, false, false, false];
            if (_bottomTasks2.Count < 7)
            {
                await Task.Delay(1000);
            }
            if (_bottomTasks2.Count < 7)
            {
                return (false, results.ToArray());
            }
            var results1 = await Task.WhenAll(_bottomTasks2);
            for (int i = 0; i < length; i++)
            {
                bool b = results1[i].Quality == Quality.Ok;
                results[i] = b;
                if (hasProducts[i])
                {
                    isSuccess &= b;
                }
            }
            return (isSuccess, results);
        }

        /// <summary>
        /// 下相机第二次飞拍结束 第二种获取结果方法
        /// </summary>
        /// <returns></returns>
        public async Task<(bool isSuccess, bool[] results)> GetBottomFlyCaptureResults2_Funcation(CaptureFlag captureFlag, bool[] hasProducts)
        {
            if (_bottomTasks2.Count() < hasProducts.Count(x => x == true))
            {
                await Task.Delay(1000);
            }
            bool[] results = new bool[hasProducts.Count()];
            if (_bottomTasks2.Count() < hasProducts.Count(x => x == true))//延迟1000ms后，检测队列还是不满足数量就NG。
            {
                return (false, results);
            }
            var resultsTmep = await Task.WhenAll(_bottomTasks2);
            int resultsTmepIndex = 0;
            for (int i = 0; i < hasProducts.Count(); i++)
            {
                if (hasProducts[i])//吸嘴有产品的
                {
                    if (resultsTmepIndex < resultsTmep.Count())
                    {
                        results[i] = resultsTmep[resultsTmepIndex].Quality == Quality.Ok ? true : false;
                        resultsTmepIndex = resultsTmepIndex + 1;
                    }
                    else //吸嘴有产品的,但是检测结果集合未找到结果，也是NG
                    {
                        results[i] = false;
                    }
                }
                else//吸嘴无产品的
                {
                    results[i] = false;
                }
            }
            return (resultsTmep.All(x => x.Quality == Quality.Ok) ? true : false, results);
        }

        /// <summary>
        /// 上相机飞拍开始
        /// </summary>
        public async Task PrepearUpFlyCapture(bool isUseSiMo1, int col, List<int> flyCaptureLists, string barcode)
        {
            _col = col;
            _flyCaptureCount = 0;
            _isUseSiMo1 = isUseSiMo1;
            _upTasks.Clear();
            _flyCaptureLists = flyCaptureLists;
            if (_productionLine.Current == null)
            {
                await _productionLine.StartAsync(new Product(barcode, 0));
            }
        }
        /// <summary>
        /// 下相机飞拍结束 取结果方法
        /// </summary>
        /// <param name="hasProducts"></param>
        /// <returns></returns>
        public async Task<(bool isSuccess, UpImageAlgorithmResult[] results)> GetUpFlyCaptureResults_Funcation(bool[] hasProducts)
        {
            if (_upTasks.Count() < hasProducts.Count(x => x == true))
            {
                await Task.Delay(1000);
            }
            UpImageAlgorithmResult[] results = new UpImageAlgorithmResult[hasProducts.Count()];
            if (_upTasks.Count() < hasProducts.Count(x => x == true))//延迟1000ms后，检测队列还是不满足数量就NG。
            {
                return (false, results);
            }
            var resultsTmep = await Task.WhenAll(_upTasks);
            int resultsTmepIndex = 0;
            for (int i = 0; i < hasProducts.Count(); i++)
            {
                int numberAbs = Math.Abs(i - 6);
                if (hasProducts[numberAbs])//有产品
                {
                    if (resultsTmepIndex < resultsTmep.Count())
                    {
                        results[numberAbs] = resultsTmep[resultsTmepIndex];
                        resultsTmepIndex = resultsTmepIndex + 1;
                    }
                    else
                    {
                        results[numberAbs] = new UpImageAlgorithmResult();
                    }
                }
                else//无产品
                {
                    results[numberAbs] = new UpImageAlgorithmResult();
                }
            }
            return (resultsTmep.All(x => x.Quality == Quality.Ok) ? true : false, results);
        }

        public async Task<bool> UpSnap(bool isUseSiMo1)
        {
            UpImage = null;
            _upCaptrueEvent.Reset();
            Electronic.Default.DO6_上相机触发.Value = true;
            await Task.Delay(50);
            Electronic.Default.DO6_上相机触发.Value = false;
            await _upCaptrueEvent.WaitOneAsync(3000, default);
            if (UpImage == null) return false;
            var up_Camera_FlyCaptureFlowBlock1 = isUseSiMo1 ? Option.Up_Camera_FlyCaptureFlowBlock1 : Option.Up_Camera_FlyCaptureFlowBlock2;
            var result = await _productionLine.AddUpImage(UpImage, new ProductPart(_isUseSiMo1, 8, 0), up_Camera_FlyCaptureFlowBlock1);
            return true;
        }

        public async Task<bool> BottomSnap()
        {
            BottomImage = null;
            _bottomCaptrueEvent.Reset();
            Electronic.Default.DO7_下相机触发.Value = true;
            await Task.Delay(50);
            Electronic.Default.DO7_下相机触发.Value = false;
            await _bottomCaptrueEvent.WaitOneAsync(3000, default);
            return BottomImage != null;
        }


        public async Task<bool> InitializeStation(CancellationToken token)
        {
            return true;
        }

        protected override async Task RunningCoreAsync()
        {
            CancellationToken.WaitHandle.WaitOne();
        }

        public void ClearAlarm()
        {
        }

        public void InitCamera()
        {
            try
            {
                TopCamera.Connect();
                UpCamera.Connect();
                BottomCamera.Connect();
                TopCamera.StopGrabbing();
                UpCamera.StopGrabbing();
                BottomCamera.StopGrabbing();
                TopCamera.TriggerMode = TriggerMode.Open;
                UpCamera.TriggerMode = TriggerMode.Open;
                BottomCamera.TriggerMode = TriggerMode.Open;
                TopCamera.StartGrabbing();
                UpCamera.StartGrabbing();
                BottomCamera.StartGrabbing();
            }
            catch (Exception ex)
            {
                LogError(ex);
            }
        }

        protected override Task PreRunning()
        {
            var storageOption = Service.GetRequiredService<IOptionRepository>().Get<DataStorageOption>();
            _inspectorOption = Service.GetRequiredService<IOptionRepository>().Get<InspectorOption>();
            Option = Recipe.Get<VisionStationOption>(Id);
            InitCamera();
            return base.PreRunning();
        }

        public override async Task InitializeAsync()
        {
            _inspectorOption = Service.GetRequiredService<IOptionRepository>().Get<InspectorOption>();
            var recipe = Service.GetRequiredService<ICurrentRecipe>();
            Option = recipe.Get<VisionStationOption>(Id);
            _platformManager.LoadProject(Option.ProjectFilePath, Option.ConcurrentLevel);
            await base.InitializeAsync();
        }
        #endregion

        public enum CaptureFlag
        {
            DuiWei_0, DuiWei_1, Detect_0, Detect_1, Calib_0, Calib_1
        }
    }
}
